package com.briup.smartcity_group1.service.impl;

import com.briup.smartcity_group1.bean.basic.Article;
import com.briup.smartcity_group1.bean.basic.BaseUser;
import com.briup.smartcity_group1.consts.ArticleStatusConsts;
import com.briup.smartcity_group1.consts.TokenColumnNameConsts;
import com.briup.smartcity_group1.dao.basic.ArticleMapper;
import com.briup.smartcity_group1.dao.ext.ArticleExtMapper;
import com.briup.smartcity_group1.dao.ext.BaseUserExtMapper;
import com.briup.smartcity_group1.exception.ServiceException;
import com.briup.smartcity_group1.service.IArticleService;
import com.briup.smartcity_group1.utils.JwtUtils;
import com.briup.smartcity_group1.utils.result.ResultCode;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.Date;

/**
 * @author congee(congee02 @ 163.com)
 * @date 1/5/2023 1:17 AM
 */
@Service
@Slf4j
public class ArticleServiceImpl implements IArticleService {

    @Autowired
    private ArticleMapper mapper;

    @Autowired
    private ArticleExtMapper extMapper;

    @Autowired
    private BaseUserExtMapper userExtMapper;

    /**
     * 修改资讯状态
     *
     * @param id     咨询信息 id
     * @param status 设置的资讯信息状态 {@link ArticleStatusConsts}
     * @throws ServiceException 咨询信息不存在 ; 期望之外的状态
     */
    @Override
    public void changeArticleStatus(int id, Integer status) throws IllegalAccessException {
        Article byPrimaryKey = mapper.selectByPrimaryKey(id);
        if (byPrimaryKey == null) {
            throw new ServiceException(ResultCode.ARTICLE_NOT_FOUND);
        }

        // 通过反射来验证状态码是否在期望中
        Class<ArticleStatusConsts> aClass = ArticleStatusConsts.class;
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field f : declaredFields) {
            Integer declaredStatus = (Integer) f.get(null);
            if (declaredStatus.equals(status)) {
                byPrimaryKey.setArticleId(id);
                byPrimaryKey.setArticleStatus(status);
                mapper.updateByPrimaryKeySelective(byPrimaryKey);
                return;
            }
        }

        // 设置的状态在期望之外
        throw new ServiceException(ResultCode.ARTICLE_UNEXPECTED_STATUS);
    }

    /**
     * 根据 id 删除咨询信息
     *
     * @param id 咨询信息id
     * @throws ServiceException 咨询信息不存在
     */
    @Override
    public void deleteArticleById(int id) {

        Article byPrimaryKey = mapper.selectByPrimaryKey(id);
        if (byPrimaryKey == null) {
            throw new ServiceException(ResultCode.ARTICLE_NOT_FOUND);
        }

        // CASCADE DELETE
        mapper.deleteByPrimaryKey(id);

    }

    /**
     * 通过id查询资讯信息
     *
     * @param id 咨询信息id
     * @return 查询到的资讯信息
     * @throws ServiceException 咨询信息不存在
     */
    @Override
    public Article findArticleById(int id) {
        Article byPrimaryKey = mapper.selectByPrimaryKey(id);
        if (byPrimaryKey == null) {
            throw new ServiceException(ResultCode.ARTICLE_NOT_FOUND);
        }
        return byPrimaryKey;
    }

    /**
     * 分页查询所有推荐的咨询信息
     *
     * @param pageNum  页码
     * @param pageSize 单页记录数量
     * @return 推荐的咨询信息的分页信息
     */
    @Override
    public PageInfo<Article> findAllRecommendedArticlesByPage(int pageNum, int pageSize) {
        return PageHelper.startPage(pageNum, pageSize)
                .doSelectPageInfo(() -> extMapper.findAllRecommendArticles());
    }

    /**
     * 分页查询所有资讯信息
     *
     * @param tittle     标题，支持模糊查询
     * @param categoryId 栏目id
     * @param status     文章状态
     * @param pageNum    页码
     * @param pageSize   单页记录数量
     * @return 咨询信息的分页信息
     */
    @Override
    public PageInfo<Article> findAllArticlesByPage(String tittle, Integer categoryId, Integer status, int pageNum, int pageSize) {
        return PageHelper.startPage(pageNum, pageSize, true).doSelectPageInfo(() ->
                extMapper.findAllLikeTittleByCategoryIdAndStatus(tittle, categoryId, status));
    }


    /**
     * 保存或更新消息信息
     * 如果参数中包含id后端认为是更新操作，如果参数中不包含id认为是插入操作
     *
     * @param article
     * @throws ServiceException 更新时咨询信息不存在
     */
    @Override
    public void saveOrUpdateArticle(Article article) {

        HttpServletRequest request =
                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        String token = request.getHeader("Authorization");

        String username = JwtUtils.getInfo(token).get(TokenColumnNameConsts.USERNAME).toString();
        BaseUser baseUser = userExtMapper.selectByName(username);

        log.info("saveOrUpdateArticle: user: {}", baseUser);

        Integer id = article.getArticleId();
        if (id == null) {
            // 插入操作
            article.setArticlePublishTime(new Date());
            article.setArticleReadTimes(0);
            article.setArticleThumpUp(0);
            article.setArticleUserId(baseUser.getUserId());
            mapper.insertSelective(article);
        } else {
            // 更新操作
            Article byPrimaryKey = mapper.selectByPrimaryKey(id);
            if (byPrimaryKey == null) {
                throw new ServiceException(ResultCode.ARTICLE_NOT_FOUND);
            }
            mapper.updateByPrimaryKeySelective(article);
        }
    }
}
